/*
 * Copyright 2006-2015 Transsion.com All right reserved. This software is the confidential and proprietary information
 * of Transsion.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it
 * only in accordance with the terms of the license agreement you entered into with Transsion.com.
 */
package com.yunji.framework_template.common.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;

import com.yunji.framework_template.common.constant.Constant;
import com.yunji.framework_template.common.http.Base64Helper;

/**
 * ClassName:SecretUtils {3DES加密解密的工具类 } <br/>
 * Date: 2015年7月30日 上午11:36:24 <br/>
 * 
 * @author fenglibin
 * @version
 * @see
 */
public class ThreeDESUtil {

    private static final Logger logger             = Logger.getLogger(ThreeDESUtil.class);
    // 定义加密算法，有DES、DESede(即3DES)、Blowfish
    private static final String Algorithm          = "DESede";
    /* 现在AF公司内部都是使用该加密KEY */
    private static final String PASSWORD_CRYPT_KEY = "1234567890abcdefghjklmno";

    public static byte[] encrypt(String src) throws UnsupportedEncodingException, NoSuchAlgorithmException,
                                             NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                                             BadPaddingException {
        return encrypt(src.getBytes(Constant.CHARSET));
    }

    /**
     * 加密方法
     * 
     * @param src 源数据的字节数组
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static byte[] encrypt(byte[] src) throws UnsupportedEncodingException, NoSuchAlgorithmException,
                                             NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                                             BadPaddingException {
        SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm); // 生成密钥
        Cipher c1 = Cipher.getInstance(Algorithm); // 实例化负责加密/解密的Cipher工具类
        c1.init(Cipher.ENCRYPT_MODE, deskey); // 初始化为加密模式
        return c1.doFinal(src);
    }

    /**
     * 将字符串进行3DES加密，并进行BASE64加密后返回
     * 
     * @param src
     * @return
     */
    public static String encryptAndGetBase64String(String src) {
        try {
            byte[] encryptBytes = encrypt(src);
            return Base64Helper.encode(encryptBytes);
        } catch (Exception e) {
            logger.error("将字符串进行3DES加密，并进行BASE64加密，发生异常：" + e.getMessage(), e);
            return null;
        }
    }

    /**
     * 解密函数
     * 
     * @param src 密文的字节数组
     * @return
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     */
    public static byte[] decrypt(byte[] src) throws UnsupportedEncodingException, InvalidKeyException,
                                             IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException,
                                             NoSuchPaddingException {
        SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
        Cipher c1 = Cipher.getInstance(Algorithm);
        c1.init(Cipher.DECRYPT_MODE, deskey); // 初始化为解密模式
        return c1.doFinal(src);
    }

    /**
     * 将字符串进行Base64解密，并再进行3DES解密，返回原始字符串
     * 
     * @param src
     * @return
     */
    public static String decryptWithBase64String(String src) {
        try {
            return new String(decrypt(Base64Helper.decodeToByteArr(src)), Constant.CHARSET);
        } catch (Exception e) {
            logger.error("将字符串并进行BASE64解密，并进行3DES解密，发生异常：" + e.getMessage(), e);
            return null;
        }
    }

    /*
     * 根据字符串生成密钥字节数组
     * @param keyStr 密钥字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    private static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24]; // 声明一个24位的字节数组，默认里面都是0
        byte[] temp = keyStr.getBytes(Constant.CHARSET); // 将字符串转成字节数组
        /*
         * 执行数组拷贝 System.arraycopy(源数组，从源数组哪里开始拷贝，目标数组，拷贝多少位)
         */
        if (key.length > temp.length) {
            // 如果temp不够24位，则拷贝temp数组整个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            // 如果temp大于24位，则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }

}
